/************************************************************************
Copyright 2003, 2004, 2005, 2006, 2007, 2008 Grid Technology Research Center,
National Institute of Advanced Industrial Science and Technology.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
************************************************************************/

package jp.aist.gtrc.plus.scheduler.specific.sge.status;

import java.util.Collection;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.LinkedList;

import jp.aist.gtrc.plus.scheduler.status.JobStatus;
import jp.aist.gtrc.plus.scheduler.status.StatusManager;
import jp.aist.gtrc.plus.scheduler.util.TextUtil;

public abstract class SGEStatusManager extends StatusManager {

	protected final LinkedHashMap<String, LinkedList<JobStatus>> jobsOnQins;
	protected final LinkedHashMap<String, LinkedList<JobStatus>> jobsOnNode;
	private static SGEStatusManager instance;

	protected SGEStatusManager() {

		super();
		jobsOnQins = new LinkedHashMap<String, LinkedList<JobStatus>>();
		jobsOnNode = new LinkedHashMap<String, LinkedList<JobStatus>>();

	}

	protected static final void setInstance(SGEStatusManager ins) {

		assert(SGEStatusManager.instance == null);
		assert(ins != null);
		SGEStatusManager.instance = ins;

	}

	protected static final SGEStatusManager getInstanceForOverride() {

		return SGEStatusManager.instance;

	}

	public static SGEStatusManager getInstance() {

		/*
		 * NOTE: Subclass must override this method.
		 * Java cannot make 'abstract static' method, so cannot set abstract here.
		 */
		assert(SGEStatusManager.instance != null);
		return SGEStatusManager.instance;

	}

	private void addJobToMap(LinkedHashMap<String, LinkedList<JobStatus>> map,
			String key, JobStatus job) {

		LinkedList<JobStatus> list = map.get(key);
		if (list == null) {
			list = new LinkedList<JobStatus>();
			map.put(key, list);
		}
		list.add(job);

	}

	protected void addJob(JobStatus job, String qinsName, String nodeName) {

		assert(isQFullname(qinsName) == true);
		assert(isQFullname(nodeName) == false);

		addJobToMap(jobsOnQins, qinsName, job);
		addJobToMap(jobsOnNode, nodeName, job);
		addJob(job);

	}

	protected final boolean isQFullname(String name) {

		return (TextUtil.isValid(name) && (name.indexOf('@') != -1));

	}

	private synchronized Collection<JobStatus> getJobs(String name) {

		Collection<JobStatus> list = isQFullname(name)
				? jobsOnQins.get(name) : jobsOnNode.get(name);
		return (list != null) ? list : new LinkedList<JobStatus>();

	}

	public synchronized Collection<JobStatus> getJobsOnNode(String nodeName) {

		assert(isQFullname(nodeName) == false);
		return getJobs(nodeName);

	}

	public synchronized Collection<JobStatus> getJobsOnQinstance(String fullName) {

		assert(isQFullname(fullName) == true);
		return getJobs(fullName);

	}

	public abstract HashMap<String, SGEUserset> getUsersetMap();
	public abstract SGEUserset getUserset(String usersetName);
	public abstract HashMap<String, SGEProject> getProjectMap();
	public abstract SGEProject getProject(String projName);
	public abstract HashMap<String, SGEParallelEnv> getParallelEnvMap();
	public abstract SGEParallelEnv getParallelEnv(String peName);
	public abstract HashMap<String, SGEHostGroup> getHostGroupMap();
	public abstract SGEHostGroup getHostGroup(String hgroupName);
	public abstract boolean isDirtyTask(SGEJobID jobID);

}
